package no.rodland.acc.model;

import org.joda.time.DateTime;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Map;

import no.rodland.acc.db.AbstractRow;

/**
 * Created by IntelliJ IDEA.
 *
 * @Since: Jun 18, 2010 12:04:32 PM
 * @Author: fmr
 */
public class Budget extends AbstractRow {

    private DateTime date;
    private BudgetAccount budgetAccount;
    private BankAccount bankAccount;
    private int amount;
    private String matched;
    private String permanent;
    private String remainder;
    private String comment;
    private String text;

    protected Budget(ResultSet rs,
                     Map<Integer, BudgetAccount> budgetAccounts,
                     Map<Integer, BankAccount> bankAccounts) throws SQLException {
        super(rs.getInt("id"),
                new DateTime(rs.getTimestamp("updated_date")),
                new DateTime(rs.getTimestamp("created_date")));
        if (budgetAccounts != null) {
            budgetAccount = budgetAccounts.get(rs.getInt("budget_account_id"));
        }
        if (bankAccounts != null) {
            bankAccount = bankAccounts.get(rs.getInt("bank_account_id"));
        }

        date = new DateTime(rs.getDate("date"));
        text = rs.getString("text");
        amount = rs.getInt("amount");
        matched = rs.getString("is_matched");
        permanent = rs.getString("is_permament");
        remainder = rs.getString("is_remainder");
        comment = rs.getString("comment");
    }

    protected Budget(Bank bank,
                     Map<Integer, BudgetAccount> budgetAccounts,
                     Map<Integer, TextBudgetAccount> textBudgetAccounts) {
        super(0, null, null);
        this.date = bank.getDate();
        this.budgetAccount = TextBudgetAccount.getBudgetAccountForText(bank.getText(), textBudgetAccounts);
        this.text = bank.getText();
        this.amount = bank.getAmount();
        this.bankAccount = bank.getBankAccount();
        this.matched = "Y";
        this.permanent = "N";
        this.remainder = "N";
        this.comment = bank.getComment();
    }

    public Budget(DateTime date,
                  BudgetAccount budgetAccount,
                  String text,
                  int amount,
                  BankAccount bankAccount,
                  String matched,
                  String permanent,
                  String remainder,
                  String comment) {
        super(0, null, null);
        this.date = date;
        this.budgetAccount = budgetAccount;
        this.text = text;
        this.amount = amount;
        this.bankAccount = bankAccount;
        this.matched = matched;
        this.permanent = permanent;
        this.remainder = remainder;
        this.comment = comment;
    }

    @Override
    public String getTableName() {
        return "budget";
    }

    @Override
    public Object[] getData() {
        return new Object[]{date.toDate(), budgetAccount.getId(), text, amount, bankAccount.getId(), matched, permanent, remainder, comment};
    }

    @Override
    public String[] getColumns() {
        return new String[]{"date", "budget_account_id", "text", "amount", "bank_account_id", "is_matched", "is_permament", "is_remainder", "comment"};
    }

    @Override
    public boolean usesIdentity() {
        return true;
    }

    /**
     * Returns the date best describing this bank.
     */
    public DateTime getDate() {
        return (date != null ? date : super.getDate());
    }

    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder();
        sb.append("Budget");
        sb.append("{date=").append(date);
        sb.append(", budgetAccount.id=").append(budgetAccount.getId());
        sb.append(", budgetAccount.name=").append(budgetAccount.getName());
        sb.append(", bankAccount.id=").append(bankAccount.getId());
        sb.append(", text=").append(text);
        sb.append(", amount=").append(amount);
        sb.append(", matched=").append(matched);
        sb.append(", permanent=").append(permanent);
        sb.append(", remainder=").append(remainder);
        sb.append(", comment='").append(comment).append('\'');
        sb.append('}');
        return sb.toString();
    }

    @Override
    public String getText() {
        return text;
    }

    @SuppressWarnings({"RedundantIfStatement"})
    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }

        Budget that = (Budget) o;

        if (getId() != 0 && that.getId() != 0 && that.getId() != getId()) {
            return false;
        }

        if (amount != that.amount) {
            return false;
        }
        if (bankAccount != null ? !bankAccount.equals(that.bankAccount) : that.bankAccount != null) {
            return false;
        }
        if (budgetAccount != null ? !budgetAccount.equals(that.budgetAccount) : that.budgetAccount != null) {
            return false;
        }
        if (comment != null ? !comment.equals(that.comment) : that.comment != null) {
            return false;
        }
        if (date != null ? !date.equals(that.date) : that.date != null) {
            return false;
        }
        if (matched != null ? !matched.equals(that.matched) : that.matched != null) {
            return false;
        }
        if (permanent != null ? !permanent.equals(that.permanent) : that.permanent != null) {
            return false;
        }
        if (remainder != null ? !remainder.equals(that.remainder) : that.remainder != null) {
            return false;
        }
        if (text != null ? !text.equals(that.text) : that.text != null) {
            return false;
        }

        return true;
    }

    @Override
    public int hashCode() {
        int result = date != null ? date.hashCode() : 0;
        result = 31 * result + (budgetAccount != null ? budgetAccount.hashCode() : 0);
        result = 31 * result + (bankAccount != null ? bankAccount.hashCode() : 0);
        result = 31 * result + amount;
        result = 31 * result + (matched != null ? matched.hashCode() : 0);
        result = 31 * result + (permanent != null ? permanent.hashCode() : 0);
        result = 31 * result + (remainder != null ? remainder.hashCode() : 0);
        result = 31 * result + (comment != null ? comment.hashCode() : 0);
        result = 31 * result + (text != null ? text.hashCode() : 0);
        return result;
    }

    public BudgetAccount getBudgetAccount() {
        return budgetAccount;
    }

    public BankAccount getBankAccount() {
        return bankAccount;
    }

    public int getAmount() {
        return amount;
    }

    public String getMatched() {
        return matched;
    }

    public String getPermanent() {
        return permanent;
    }

    public String getRemainder() {
        return remainder;
    }

    public String getComment() {
        return comment;
    }
}